package org.example;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.example.config.AnalysisConfig;
import org.example.service.ApkProcessor;
import org.example.service.DatabaseService;
import org.example.service.ExcelExporter;
import org.example.util.FileUtils;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ApkAnalyzer {
    // 添加缓存字段
    private static Set<String> cachedKnownPackages = null;
    
    // 添加带缓存的加载方法
    private static Set<String> loadKnownPackages(String jsonPath) {
        if (cachedKnownPackages != null) {
            return cachedKnownPackages;
        }
        
        try {
            // 实际加载逻辑保持与Python版类似
            File jsonFile = new File(jsonPath);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode rootNode = objectMapper.readTree(jsonFile);
            ArrayNode packagesNode = (ArrayNode) rootNode.get("packages");
            
            Set<String> packages = new HashSet<>();
            packagesNode.forEach(node -> packages.add(node.asText()));
            
            cachedKnownPackages = Collections.unmodifiableSet(packages);
            return cachedKnownPackages;
        } catch (Exception e) {
            return Collections.emptySet();
        }
    }
    
    public static void main(String[] args) {
        // 加载配置
        AnalysisConfig config = new AnalysisConfig();
        String outputDir = "D:/apk/output";
        config.setOutputDir(outputDir);
        config.setKnownPackages(loadKnownPackages("D:/apk/packages.json"));
        config.setPreferredArchs(List.of("armeabi-v7a", "arm64-v8a"));

        // 创建输出目录
        new File(outputDir).mkdirs();

        // 初始化数据库（使用带参数的新方法）
        DatabaseService dbService = new DatabaseService();
        dbService.initDatabase();

        // 处理 APK 文件夹
        File apkFolder = new File("D:/apk");
        File[] apkFiles = apkFolder.listFiles((dir, name) -> name.endsWith(".apk"));
        
        if (apkFiles == null) {
            System.err.println("APK文件夹路径无效或不可访问: " + apkFolder.getAbsolutePath());
            return;
        }

        // 使用多线程并行处理
        int processors = Runtime.getRuntime().availableProcessors();
        int threadPoolSize = Math.min(processors * 2, apkFiles.length); // 限制线程数
        ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
        
        // 用于收集结果的列表
        List<Future<AnalysisResult>> futures = new ArrayList<>();
        AtomicInteger processedCount = new AtomicInteger(0);
        
        System.out.println("开始并行处理 " + apkFiles.length + " 个APK文件，使用 " + threadPoolSize + " 个线程...");
        
        // 提交所有任务
        for (File apkFile : apkFiles) {
            Future<AnalysisResult> future = executor.submit(() -> {
                try {
                    ApkProcessor processor = new ApkProcessor();
                    Map<String, String> deps = processor.analyzeApk(apkFile.getAbsolutePath(), config);
                    
                    int current = processedCount.incrementAndGet();
                    System.out.println("处理进度: " + current + "/" + apkFiles.length + " - " + apkFile.getName());
                    
                    return new AnalysisResult(
                        FileUtils.calculateFileHash(apkFile.getAbsolutePath(), "SHA-256"),
                        FileUtils.getApkName(apkFile.getAbsolutePath()),
                        deps
                    );
                } catch (Exception e) {
                    System.err.println("处理APK文件失败: " + apkFile.getName() + " - " + e.getMessage());
                    return null;
                }
            });
            futures.add(future);
        }
        
        // 批量收集结果并保存到数据库
        List<DatabaseService.DependencyEntry> batchEntries = new ArrayList<>();
        int batchSize = 100; // 每100个结果批量保存一次
        
        for (int i = 0; i < futures.size(); i++) {
            try {
                AnalysisResult result = futures.get(i).get();
                if (result != null) {
                    // 将结果转换为批量条目
                    for (Map.Entry<String, String> entry : result.dependencies.entrySet()) {
                        batchEntries.add(new DatabaseService.DependencyEntry(
                            result.apkHash, 
                            result.apkName, 
                            entry.getKey(), 
                            entry.getValue()
                        ));
                    }
                    
                    // 当达到批处理大小或是最后一个结果时，执行批量保存
                    if (batchEntries.size() >= batchSize || i == futures.size() - 1) {
                        if (!batchEntries.isEmpty()) {
                            dbService.saveDependenciesBatch(batchEntries);
                            System.out.println("批量保存了 " + batchEntries.size() + " 条依赖记录");
                            batchEntries.clear();
                        }
                    }
                }
            } catch (Exception e) {
                System.err.println("获取处理结果时发生错误: " + e.getMessage());
            }
        }
        
        // 关闭线程池
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
        }
        
        System.out.println("所有APK文件处理完成！");

        // 导出 Excel
        ExcelExporter exporter = new ExcelExporter();
        exporter.exportToExcel("apk_dependencies.xlsx");
    }
    
    // 用于存储分析结果的内部类
    private static class AnalysisResult {
        final String apkHash;
        final String apkName;
        final Map<String, String> dependencies;
        
        AnalysisResult(String apkHash, String apkName, Map<String, String> dependencies) {
            this.apkHash = apkHash;
            this.apkName = apkName;
            this.dependencies = dependencies;
        }
    }
}